package com.ouc.dcrms.video;

import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;

import java.awt.Frame;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.WindowConstants;

/*****************************************************************************
 * 类 ： JDialogVoiceTalk 
 * 类描述 ：语音对讲
 ****************************************************************************/
public class JDialogVoiceTalk extends JDialog {
    private static final long serialVersionUID = -6354306351002275782L;

    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    NativeLong m_lUserID;// 用户ID
    HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;// 设备信息
    HCNetSDK.NET_DVR_WORKSTATE_V30 m_strWorkState;// 工作状态
    FVoiceDataCallBack fVoiceDataCallBack;// 回调函数
    int m_iSel;// 音频通道
    boolean m_bInitialed;// 对话框是否已初始化

    FileWriter fLocal;// 本地音频文件
    FileWriter fDevice;// 设备发送的音频文件

    /*************************************************
     * 函数: JDialogVoiceTalk 
     * 函数描述: 构造函数 Creates new form JDialogVoiceTalk
     *************************************************/
    public JDialogVoiceTalk(Frame parent, boolean modal,
	    NativeLong lUserID, HCNetSDK.NET_DVR_DEVICEINFO_V30 strDeviceInfo) {
	super(parent, modal);
	try {
	    initComponents();
	    m_lUserID = lUserID;
	    m_strDeviceInfo = strDeviceInfo;
	    m_iSel = 0;
	    fVoiceDataCallBack = new FVoiceDataCallBack();
	    fLocal = new FileWriter("D:\\local.264");
	    fDevice = new FileWriter("D:\\device.264");

	    // 初始化对话框
	    initialDialog();
	    m_bInitialed = true;
	} catch (IOException ex) {
	    Logger.getLogger(JDialogVoiceTalk.class.getName()).log(
		    Level.SEVERE, null, ex);
	}
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed"
    // desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

	jPanel = new JPanel();
	jLabel1 = new JLabel();
	jComboBoxVoiceChannel = new JComboBox<Object>();
	jLabelStatus = new JLabel();
	jButtonStart = new JButton();
	jButtonStop = new JButton();
	jLabel2 = new JLabel();
	jComboBoxDataType = new JComboBox<Object>();
	jButtonRefresh = new JButton();
	jButtonExit = new JButton();

	setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	setTitle("语音对讲");

	jPanel.setBorder(BorderFactory.createTitledBorder(""));

	jLabel1.setText("对讲通道");

	jComboBoxVoiceChannel
		.addActionListener(new java.awt.event.ActionListener() {
		    public void actionPerformed(java.awt.event.ActionEvent evt) {
			jComboBoxVoiceChannelActionPerformed(evt);
		    }
		});

	jLabelStatus.setText("未占用");

	jButtonStart.setText("开始对讲");
	jButtonStart.addActionListener(new java.awt.event.ActionListener() {
	    public void actionPerformed(java.awt.event.ActionEvent evt) {
		jButtonStartActionPerformed(evt);
	    }
	});

	jButtonStop.setText("停止对讲");
	jButtonStop.addActionListener(new java.awt.event.ActionListener() {
	    public void actionPerformed(java.awt.event.ActionEvent evt) {
		jButtonStopActionPerformed(evt);
	    }
	});

	jLabel2.setText("回调数据类型");

	jComboBoxDataType.setModel(new DefaultComboBoxModel<Object>(
		new String[] { "非PCM", "PCM" }));

	GroupLayout jPanelLayout = new GroupLayout(jPanel);
	jPanel.setLayout(jPanelLayout);
	jPanelLayout
		.setHorizontalGroup(jPanelLayout
			.createParallelGroup(GroupLayout.Alignment.LEADING)
			.addGroup(
				jPanelLayout
					.createSequentialGroup()
					.addGroup(
						jPanelLayout
							.createParallelGroup(
								GroupLayout.Alignment.LEADING)
							.addGroup(
								jPanelLayout
									.createSequentialGroup()
									.addGap(18,
										18,
										18)
									.addGroup(
										jPanelLayout
											.createParallelGroup(
												GroupLayout.Alignment.LEADING)
											.addGroup(
												jPanelLayout
													.createSequentialGroup()
													.addComponent(
														jButtonStart)
													.addGap(36,
														36,
														36)
													.addComponent(
														jButtonStop))
											.addGroup(
												jPanelLayout
													.createSequentialGroup()
													.addComponent(
														jLabel1)
													.addGap(18,
														18,
														18)
													.addComponent(
														jComboBoxVoiceChannel,
														GroupLayout.PREFERRED_SIZE,
														82,
														GroupLayout.PREFERRED_SIZE)
													.addGap(28,
														28,
														28)
													.addComponent(
														jLabelStatus,
														GroupLayout.PREFERRED_SIZE,
														45,
														GroupLayout.PREFERRED_SIZE))))
							.addGroup(
								jPanelLayout
									.createSequentialGroup()
									.addGap(86,
										86,
										86)
									.addComponent(
										jLabel2)
									.addPreferredGap(
										LayoutStyle.ComponentPlacement.UNRELATED)
									.addComponent(
										jComboBoxDataType,
										GroupLayout.PREFERRED_SIZE,
										GroupLayout.DEFAULT_SIZE,
										GroupLayout.PREFERRED_SIZE)))
					.addContainerGap(
						GroupLayout.DEFAULT_SIZE,
						Short.MAX_VALUE)));
	jPanelLayout.setVerticalGroup(jPanelLayout.createParallelGroup(
		GroupLayout.Alignment.LEADING).addGroup(
		jPanelLayout
			.createSequentialGroup()
			.addContainerGap()
			.addGroup(
				jPanelLayout
					.createParallelGroup(
						GroupLayout.Alignment.BASELINE)
					.addComponent(jLabel1)
					.addComponent(jComboBoxVoiceChannel,
						GroupLayout.PREFERRED_SIZE,
						GroupLayout.DEFAULT_SIZE,
						GroupLayout.PREFERRED_SIZE)
					.addComponent(jLabelStatus))
			.addGap(18, 18, 18)
			.addGroup(
				jPanelLayout
					.createParallelGroup(
						GroupLayout.Alignment.BASELINE)
					.addComponent(jButtonStart)
					.addComponent(jButtonStop))
			.addGap(18, 18, 18)
			.addGroup(
				jPanelLayout
					.createParallelGroup(
						GroupLayout.Alignment.BASELINE)
					.addComponent(jLabel2)
					.addComponent(jComboBoxDataType,
						GroupLayout.PREFERRED_SIZE,
						GroupLayout.DEFAULT_SIZE,
						GroupLayout.PREFERRED_SIZE))
			.addContainerGap(GroupLayout.DEFAULT_SIZE,
				Short.MAX_VALUE)));

	jButtonRefresh.setText("刷新");
	jButtonRefresh.addActionListener(new java.awt.event.ActionListener() {
	    public void actionPerformed(java.awt.event.ActionEvent evt) {
		jButtonRefreshActionPerformed(evt);
	    }
	});

	jButtonExit.setText("退出");
	jButtonExit.addActionListener(new java.awt.event.ActionListener() {
	    public void actionPerformed(java.awt.event.ActionEvent evt) {
		jButtonExitActionPerformed(evt);
	    }
	});

	GroupLayout layout = new GroupLayout(getContentPane());
	getContentPane().setLayout(layout);
	layout.setHorizontalGroup(layout
		.createParallelGroup(GroupLayout.Alignment.LEADING)
		.addGroup(
			layout.createSequentialGroup()
				.addGap(34, 34, 34)
				.addComponent(jButtonRefresh)
				.addPreferredGap(
					LayoutStyle.ComponentPlacement.RELATED,
					97, Short.MAX_VALUE)
				.addComponent(jButtonExit).addGap(40, 40, 40))
		.addGroup(
			layout.createSequentialGroup()
				.addContainerGap()
				.addComponent(jPanel,
					GroupLayout.PREFERRED_SIZE,
					GroupLayout.DEFAULT_SIZE,
					GroupLayout.PREFERRED_SIZE)
				.addContainerGap(GroupLayout.DEFAULT_SIZE,
					Short.MAX_VALUE)));
	layout.setVerticalGroup(layout.createParallelGroup(
		GroupLayout.Alignment.LEADING)
		.addGroup(
			layout.createSequentialGroup()
				.addContainerGap()
				.addComponent(jPanel,
					GroupLayout.PREFERRED_SIZE,
					GroupLayout.DEFAULT_SIZE,
					GroupLayout.PREFERRED_SIZE)
				.addPreferredGap(
					LayoutStyle.ComponentPlacement.RELATED)
				.addGroup(
					layout.createParallelGroup(
						GroupLayout.Alignment.LEADING)
						.addComponent(jButtonRefresh)
						.addComponent(jButtonExit))
				.addContainerGap()));

	pack();
    }// </editor-fold>//GEN-END:initComponents

    /*************************************************
     * 函数: "开始对讲" 按钮单击响应函数 函数描述: 开始对讲
     *************************************************/
    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt)// GEN-FIRST:event_jButtonStartActionPerformed
    {// GEN-HEADEREND:event_jButtonStartActionPerformed
     // 这里采用全局的句柄进行操作,因为子对话框销毁后语音对讲还可以进行,用全局的变量保存句柄
	ClientDemo.g_lVoiceHandle = hCNetSDK.NET_DVR_StartVoiceCom_V30(
		m_lUserID, m_iSel + 1,
		jComboBoxDataType.getSelectedIndex() == 1, fVoiceDataCallBack,
		null);
	if (ClientDemo.g_lVoiceHandle.intValue() == -1) {
	    JOptionPane.showMessageDialog(this, "语音对讲失败");
	    return;
	}
	EnableCtrl();
    }// GEN-LAST:event_jButtonStartActionPerformed

    /*************************************************
     * 函数: "停止对讲" 按钮单击响应函数 函数描述: 停止对讲
     *************************************************/
    private void jButtonStopActionPerformed(java.awt.event.ActionEvent evt)// GEN-FIRST:event_jButtonStopActionPerformed
    {// GEN-HEADEREND:event_jButtonStopActionPerformed
	if (ClientDemo.g_lVoiceHandle.intValue() >= 0) {
	    if (hCNetSDK.NET_DVR_StopVoiceCom(ClientDemo.g_lVoiceHandle)) {
		ClientDemo.g_lVoiceHandle.setValue(-1);
	    } else {
		JOptionPane.showMessageDialog(this, "关闭对讲失败");
	    }
	}
	EnableCtrl();
    }// GEN-LAST:event_jButtonStopActionPerformed

    /*************************************************
     * 函数: "对讲通道" 选项改变事件响应函数 函数描述: 显示通道状态
     *************************************************/
    private void jComboBoxVoiceChannelActionPerformed(
	    java.awt.event.ActionEvent evt)// GEN-FIRST:event_jComboBoxVoiceChannelActionPerformed
    {// GEN-HEADEREND:event_jComboBoxVoiceChannelActionPerformed
	if (!m_bInitialed) {
	    return;
	}
	m_iSel = jComboBoxVoiceChannel.getSelectedIndex();
	if (0 == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setText("未使用");
	    jLabelStatus.setVisible(true);
	} else if (1 == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setText("已使用");
	    jLabelStatus.setVisible(true);
	} else if (0xff == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setVisible(false);
	}
    }// GEN-LAST:event_jComboBoxVoiceChannelActionPerformed

    /*************************************************
     * 函数: "刷新" 按钮单击响应函数 函数描述: 刷新状态
     *************************************************/
    private void jButtonRefreshActionPerformed(java.awt.event.ActionEvent evt)// GEN-FIRST:event_jButtonRefreshActionPerformed
    {// GEN-HEADEREND:event_jButtonRefreshActionPerformed
	if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(m_lUserID, m_strWorkState)) {
	    JOptionPane.showMessageDialog(this, "获取工作状态失败");
	    jLabelStatus.setVisible(false);
	    return;
	}

	m_iSel = jComboBoxVoiceChannel.getSelectedIndex();
	if (0 == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setText("未使用");
	    jLabelStatus.setVisible(true);
	} else if (1 == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setText("已使用");
	    jLabelStatus.setVisible(true);
	} else if (0xff == m_strWorkState.byAudioChanStatus[m_iSel]) {
	    jLabelStatus.setVisible(false);
	}
    }// GEN-LAST:event_jButtonRefreshActionPerformed

    /*************************************************
     * 函数: "退出" 按钮单击响应函数 函数描述: 销毁对话框
     *************************************************/
    private void jButtonExitActionPerformed(java.awt.event.ActionEvent evt)// GEN-FIRST:event_jButtonExitActionPerformed
    {// GEN-HEADEREND:event_jButtonExitActionPerformed
	dispose();
    }// GEN-LAST:event_jButtonExitActionPerformed

    /*************************************************
     * 函数: initialDialog 函数描述: 初始化对话框
     *************************************************/
    private void initialDialog() {
	EnableCtrl();
	switch (m_strDeviceInfo.byAudioChanNum) {
	case 1:
	    jComboBoxVoiceChannel.addItem("Audio1");
	    break;
	case 2:
	    jComboBoxVoiceChannel.addItem("Audio1");
	    jComboBoxVoiceChannel.addItem("Audio2");
	    break;
	default:
	    break;
	}

	m_strWorkState = new HCNetSDK.NET_DVR_WORKSTATE_V30();
	if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(m_lUserID, m_strWorkState)) {
	    JOptionPane.showMessageDialog(this, "获取工作状态失败");
	    jLabelStatus.setVisible(false);
	} else {

	    if (0 == m_strWorkState.byAudioChanStatus[m_iSel]) {
		jLabelStatus.setText("未使用");
		jLabelStatus.setVisible(true);
	    } else {
		if (1 == m_strWorkState.byAudioChanStatus[m_iSel]) {
		    jLabelStatus.setText("已使用");
		    jLabelStatus.setVisible(true);
		} else {
		    if (0xff == m_strWorkState.byAudioChanStatus[m_iSel]) {
			jLabelStatus.setVisible(false);
		    }
		}
	    }
	}
    }

    /*************************************************
     * 函数: EnableCtrl 函数描述: 控件Enable属性
     *************************************************/
    private void EnableCtrl() {
	boolean bVoiceTalk = false;
	if (ClientDemo.g_lVoiceHandle.intValue() >= 0) {
	    bVoiceTalk = true;
	    jLabelStatus.setText("已使用");
	} else {
	    bVoiceTalk = false;
	    jLabelStatus.setText("未使用");
	}
	jButtonStart.setEnabled(!bVoiceTalk);
	jButtonStop.setEnabled(bVoiceTalk);
	jComboBoxVoiceChannel.setEnabled(!bVoiceTalk);
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JButton jButtonExit;
    private JButton jButtonRefresh;
    private JButton jButtonStart;
    private JButton jButtonStop;
    private JComboBox<Object> jComboBoxDataType;
    private JComboBox<Object> jComboBoxVoiceChannel;
    private JLabel jLabel1;
    private JLabel jLabel2;
    private JLabel jLabelStatus;
    private JPanel jPanel;

    // End of variables declaration//GEN-END:variables

    /******************************************************************************
     * 内部类: FVoiceDataCallBack 实现对讲音频数据回调
     ******************************************************************************/
    class FVoiceDataCallBack implements HCNetSDK.FVoiceDataCallBack_V30 {
	// 对对讲的音频数据进行回调操作,以下写入文件操作
	public void invoke(NativeLong lVoiceComHandle, String pRecvDataBuffer,
		int dwBufSize, byte byAudioFlag, Pointer pUser) {
	    // byAudioFlag为0表示本地文件,为1表示设备的音频文件
	    if (byAudioFlag == 0) {
		try {
		    fLocal.write(pRecvDataBuffer);
		    fLocal.flush();
		} catch (IOException ex) {
		    Logger.getLogger(JDialogVoiceTalk.class.getName()).log(
			    Level.SEVERE, null, ex);
		}
	    } else {
		if (byAudioFlag == 1) {
		    try {
			fDevice.write(pRecvDataBuffer);
			fDevice.flush();
		    } catch (IOException ex) {
			Logger.getLogger(JDialogVoiceTalk.class.getName()).log(
				Level.SEVERE, null, ex);
		    }
		}
	    }
	}
    }

}
